// Ch4_4.cpp : Initialization functions

// CH4_4.cpp
// by Charles Mc Auley
// "Programming AutoCAD 2000 with ObjectARX"
//
// This is a redo of sample application CH3_2.ARX
// in which we used result buffers and selection set
// to change the layer of selected entities to that of
// a target layer. Now that we understand entities and
// the database, you can see that changing an entities
// layer is much simpler than that of CH3_2.ARX
//
/////////////////////////////////////////////////////////

#include "StdAfx.h"
#include "StdArx.h"
#include "resource.h"

HINSTANCE _hdllInstance =NULL ;

// This command registers an ARX command.
void AddCommand(const char* cmdGroup, const char* cmdInt, const char* cmdLoc,
				const int cmdFlags, const AcRxFunctionPtr cmdProc, const int idLocal = -1);

// NOTE: DO NOT edit the following lines.
//{{AFX_ARX_MSG
void InitApplication();
void UnloadApplication();
//}}AFX_ARX_MSG

// NOTE: DO NOT edit the following lines.
//{{AFX_ARX_ADDIN_FUNCS
//}}AFX_ARX_ADDIN_FUNCS

/////////////////////////////////////////////////////////////////////////////
// DLL Entry Point
extern "C"
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
{
	if (dwReason == DLL_PROCESS_ATTACH)
	{
        _hdllInstance = hInstance;
	} else if (dwReason == DLL_PROCESS_DETACH) {
	}
	return TRUE;    // ok
}



/////////////////////////////////////////////////////////////////////////////
// ObjectARX EntryPoint
extern "C" AcRx::AppRetCode 
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
	switch (msg) {
	case AcRx::kInitAppMsg:
		// Comment out the following line if your
		// application should be locked into memory
		acrxDynamicLinker->unlockApplication(pkt);
		acrxDynamicLinker->registerAppMDIAware(pkt);
		InitApplication();
		break;
	case AcRx::kUnloadAppMsg:
		UnloadApplication();
		break;
	}
	return AcRx::kRetOK;
}


// Init this application. Register your
// commands, reactors...
void InitApplication()
{
	// NOTE: DO NOT edit the following lines.
	//{{AFX_ARX_INIT
	AddCommand("CH4_APPS", "CEL", "CEL", ACRX_CMD_MODAL, cel);
	//}}AFX_ARX_INIT

	// TODO: add your initialization functions
	acutPrintf("\nType \"CEL\" to execute. ");
}

// Unload this application. Unregister all objects
// registered in InitApplication.
void UnloadApplication()
{
	// NOTE: DO NOT edit the following lines.
	//{{AFX_ARX_EXIT
	acedRegCmds->removeGroup("CH4_APPS");
	//}}AFX_ARX_EXIT

	// TODO: clean up your application
	acutPrintf("%s%s", "Goodbye\n", "Removing command group \"CH4_APPS\"\n");
}

// This functions registers an ARX command.
// It can be used to read the localized command name
// from a string table stored in the resources.
void AddCommand(const char* cmdGroup, const char* cmdInt, const char* cmdLoc,
				const int cmdFlags, const AcRxFunctionPtr cmdProc, const int idLocal)
{
	char cmdLocRes[65];

	// If idLocal is not -1, it's treated as an ID for
	// a string stored in the resources.
	if (idLocal != -1) {

		// Load strings from the string table and register the command.
		::LoadString(_hdllInstance, idLocal, cmdLocRes, 64);
		acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLocRes, cmdFlags, cmdProc);

	} else
		// idLocal is -1, so the 'hard coded'
		// localized function name is used.
		acedRegCmds->addCommand(cmdGroup, cmdInt, cmdLoc, cmdFlags, cmdProc);
}

// User defined function
// called by cnl(), see
// Ch4_4Commands.cpp
void chgEntsLyr(ads_name ent, ads_name srcSS)
{
	AcDbEntity *pEnt;
	AcDbObjectId entId, lyrId;
	long lenSS;
	ads_name ssEnt;
	int rc;

	// Verify that there are entities in
	// the selection set
	rc = acedSSLength(srcSS, &lenSS);
	if(rc != RTNORM)
	{
		acutPrintf("\nInvalid or empty selection set");
		return;
	}

	acdbGetObjectId(entId, ent);

	acdbOpenAcDbEntity(pEnt, entId, AcDb::kForRead);
	lyrId = pEnt->layerId();
	pEnt->close();

	// Now the we have the target entity layer
	// substitute the layer record for each entity
	// in the selection set.

	for(long i = 0; i < lenSS; i++)
	{
		// Get the entity name at the specified index
		rc = acedSSName(srcSS, i, ssEnt);
		if(rc != RTNORM)
		{
			break;
		}

		// Get the entity objectId from the entity name
		acdbGetObjectId(entId, ssEnt);

		acdbOpenAcDbEntity(pEnt, entId, AcDb::kForWrite);
		pEnt->setLayer(lyrId);
		pEnt->close();
	}
}